using System;
using System.Reflection;
using Common.Logging;
using NServiceBus;
using NServiceBus.Config;
using NServiceBus.Management;
using NServiceBus.Management.Config;
using NServiceBus.Management.Managers;
using NServiceBus.Management.Messages.EndpointCommandMessages;
using NServiceBus.Management.Messages.EndpointStatusMessages;
using NServiceBus.Unicast.Config;
using NServiceBus.Unicast.Subscriptions.Msmq;
using NServiceBus.Unicast.Transport;
using NServiceBus.Unicast.Transport.Msmq.Config;
using NServiceBus.Unicast.Subscriptions.Msmq.Config;

namespace Server
{
    class Program
    {
        static void Main()
        {
            LogManager.GetLogger("hello").Debug("Started.");
            ObjectBuilder.CastleFramework.Builder builder = new ObjectBuilder.CastleFramework.Builder();

         //   Configure.With(builder).SagasAndMessageHandlersIn(Assembly.GetExecutingAssembly());
            Configure.With(builder).SagasAndMessageHandlersIn(typeof(EndpointCommandManager).Assembly);

            new ConfigMsmqSubscriptionStorage(builder);

            new ConfigMsmqTransport(builder)
                .IsTransactional(true)
                .PurgeOnStartup(false)
                .UseXmlSerialization(false);

            new ConfigUnicastBus(builder)
                .ImpersonateSender(false)
                .SetMessageHandlersFromAssembliesInOrder(typeof(EndpointCommandManager).Assembly);

            new ConfigManagement(builder);
            
            IBus bus = builder.Build<IBus>();
            ITransport transport = builder.Build<ITransport>();

            transport.TransportMessageReceived += HandleTransportMessageReceived;

            EndpointManager manager = builder.Build<EndpointManager>();

            bus.Start();

            manager.Start();

            bus.Subscribe(typeof(EndpointPingResponseCommand));

            WriteMenu();
            string read;
            while ((read = Console.ReadLine().ToLower()) != "q")
            {                
                int number;
                if (!int.TryParse(read, out number))
                    number = 1;

                switch(number)
                {
                    case 1:
                        bus.Publish(new EndpointPingCommand());
                        break;
                    case 2:
                        bus.Publish(new EndpointPingResponseCommand());
                        break;
                }
            }
        }

        private static void WriteMenu()
        {
            Console.WriteLine("PubSub Server Menu");
            Console.WriteLine("1 = SendPingCommand");
            Console.WriteLine("2 = SendPingResponseCommand");
            Console.WriteLine("q = Quit");
        }

        private static void HandleTransportMessageReceived(object sender, TransportMessageReceivedEventArgs eventArgs)
        {
            foreach (IMessage mess in eventArgs.Message.Messages)
            {
                Console.Write("Message received, message type: " + mess.GetType() + "\n");
            }
        }
    }
}
